package com.ksyun.start.camp.service.impl;

import com.fasterxml.jackson.datatype.jsr310.ser.ZonedDateTimeSerializer;
import com.google.gson.Gson;
import com.ksyun.start.camp.model.ApiResponse;
import com.ksyun.start.camp.model.InstanceFromTime;
import com.ksyun.start.camp.model.ResponseFromTime;
import com.ksyun.start.camp.model.ServiceInstance;
import com.ksyun.start.camp.model.vo.ApiServiceInstance;
import com.ksyun.start.camp.model.vo.ServiceInstanceVO;
import com.ksyun.start.camp.service.TimeService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.util.List;

/**
 * 代表远端时间服务接口实现
 */
@Component
@Slf4j
public class TimeServiceImpl implements TimeService {

    @Autowired
    private RestTemplate restTemplate;
    @Autowired
    private Gson gson;

    private final String TIME_SERVICE = "/api/getDateTime?style=";

    private final String REGISTRY_URL = "http://localhost:8180/api/discovery?name=";


    // 获取客户端信息的方法
    public ApiResponse<ResponseFromTime> getDateTime(String style) {
        String response = null;
        try {
            String domain = getDomain("time-service");
            String timeServiceURL= domain+TIME_SERVICE;
            // 3. 执行远程调用，获取指定格式的时间
            // 调用简单时间服务接口获取完整时间信息
            response = restTemplate.getForObject(timeServiceURL+style, String.class);

            InstanceFromTime instanceFromTime = gson.fromJson(response, InstanceFromTime.class);
            String serviceId = instanceFromTime.getData().getServiceId();
            //这里的GMTTime是格林尼治标准时间（GMT），需要将其时间时区改为中国标准时间（即北京时间）
            String GMTTime = instanceFromTime.getData().getResult();
            String chinaTime = getChinaTime(GMTTime, style);
            log.info("格林尼治标准时间（GMT）为:{},北京时间为:{}",GMTTime,chinaTime);
            ResponseFromTime responseFromTime = new ResponseFromTime(null,
                    "Hello Kingsoft Clound Star Camp - [" + serviceId + "] - " + chinaTime);
            return new ApiResponse<>(200, responseFromTime);
        } catch (Exception e) {
            // 如果简单时间服务不可用，返回错误信息
            ResponseFromTime responseFromTime = new ResponseFromTime("简单时间服务不可用", null);
            return new ApiResponse<>(502, responseFromTime);
        }
    }

    // 从注册中心轮询获取服务ip和端口
    private String getDomain(String service) {
        String url = REGISTRY_URL + service;
        // 1. 连接到 registry 服务，获取远端服务列表
        String serviceResponse = restTemplate.getForObject(url, String.class);
        ApiServiceInstance serviceInstanceByDiscovery = gson.fromJson(serviceResponse, ApiServiceInstance.class);
        List<ServiceInstanceVO> serviceInstanceVOList = serviceInstanceByDiscovery.getData();

        // 2. 从远端服务列表中获取一个服务实例
        ServiceInstanceVO serviceInstanceVO = serviceInstanceVOList.get(0);
        String ipAddress = serviceInstanceVO.getIpAddress();
        Integer port = serviceInstanceVO.getPort();
        String domain = "http://" + ipAddress + ":" + port;
        return domain;
    }

    private String getChinaTime(String GMTTime, String style) {
        DateTimeFormatter formatter;
        LocalDateTime localDateTime;
        ZoneId chinaZoneId = ZoneId.of("Asia/Shanghai");
        ZonedDateTime zonedDateTime;
        LocalDateTime chinaLocalTime;
        String chinaTime="";
        try {
            switch (style) {
                case "full":
                    formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
                    localDateTime = LocalDateTime.parse(GMTTime, formatter);
                    zonedDateTime = localDateTime.atZone(ZoneOffset.UTC);
                    chinaLocalTime = zonedDateTime.withZoneSameInstant(chinaZoneId).toLocalDateTime();
                    chinaTime = chinaLocalTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
                    break;
                case "date":
                    formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
                    localDateTime = LocalDate.parse(GMTTime, formatter).atStartOfDay();
                    zonedDateTime = localDateTime.atZone(ZoneOffset.UTC);
                    chinaLocalTime = zonedDateTime.withZoneSameInstant(chinaZoneId).toLocalDateTime();
                    chinaTime = chinaLocalTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
                    break;
                case "time":
                    formatter = DateTimeFormatter.ofPattern("HH:mm:ss");
                    localDateTime = LocalTime.parse(GMTTime, formatter).atDate(LocalDate.now());
                    zonedDateTime = localDateTime.atZone(ZoneOffset.UTC);
                    chinaLocalTime = zonedDateTime.withZoneSameInstant(chinaZoneId).toLocalDateTime();
                    chinaTime = chinaLocalTime.format(DateTimeFormatter.ofPattern("HH:mm:ss"));
                    break;
                case "unix":
                    //北京时间和格林时间时间戳一样
                    long unixTimestamp = Long.parseLong(GMTTime);
                    chinaTime = String.valueOf(unixTimestamp);
                    break;
                default://确保在用户没有传值情况下默认返回full类型的时间
                    formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS");
                    localDateTime = LocalDateTime.parse(GMTTime, formatter);
                    zonedDateTime = localDateTime.atZone(ZoneOffset.UTC);
                    chinaLocalTime = zonedDateTime.withZoneSameInstant(chinaZoneId).toLocalDateTime();
                    chinaTime = chinaLocalTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
                    break;
            }
            return chinaTime;
        } catch (DateTimeParseException e) {
            throw new IllegalArgumentException("日期时间格式不正确: " + GMTTime);
        }
    }


}
